package com.ymm.system.core.facade;

import com.ymm.system.api.constants.CargoEntity;
import com.ymm.system.api.dto.ShipperCargoBriefResponse;
import com.ymm.system.api.dto.ShipperCargoDetailResponse;
import com.ymm.system.api.dto.PutOnCargoRequest;
import com.ymm.system.api.facade.SystemCargoService;
import com.ymm.system.api.facade.SystemShipperCargoService;
import com.ymm.system.api.utils.CargoStatusEnum;
import com.ymm.system.api.utils.Result;
import com.ymm.system.api.utils.ResultCodeEnum;
import com.ymm.system.core.constants.OpsPersonTypeEnum;
import com.ymm.system.core.mq.sender.CargoPutOnMsgSender;
import com.ymm.system.core.utils.UploadFileUtils;
import com.ymm.system.dao.mapper.CargoMapper;

import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

/**
 * @Author zikang.yao
 * @Description TODO
 * @Date 2022/8/4 21:47
 * @Version 1.0
 */
@Service(version = "server")
@Slf4j
@Component
public class SystemShipperCargoServiceImpl implements SystemShipperCargoService {

    /**
     * cargo DAO
     */
    @Resource
    private CargoMapper cargoMapper;

    @Resource
    private SystemCargoService systemCargoService;

    @Resource
    private CargoPutOnMsgSender cargoPutOnMsgSender;

    /**
     * 上架货源服务
     *
     * @param putOnCargoRequest 发货request
     * @Param: [cargoDTO]
     * @return: void
     */
    @Override
    public Result<Long> cargoDeliver(PutOnCargoRequest putOnCargoRequest, Long shipperId) {
        return systemCargoService.cargoDeliver(putOnCargoRequest, OpsPersonTypeEnum.SHIPPER.getCode(), shipperId);
    }

    @Override
    public Result<Long> payForCargoSuccess(Long shipperId, Long cargoId) {
        if (Objects.isNull(shipperId) || Objects.isNull(cargoId)) {
            return Result.fail(null, ResultCodeEnum.PARAM_ERROR);
        }
        cargoMapper.updateCargoState(cargoId, CargoStatusEnum.ON_SHLFE.getCode());
        //给货主端发消息
        try {
            cargoPutOnMsgSender.send(cargoId, shipperId, OpsPersonTypeEnum.SHIPPER.getCode(), shipperId);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("消息发送错误");
        }
        return Result.success(cargoId);
    }

    /**
     * 下架货源服务
     *
     * @param cargoId 货源Id
     * @Param: [cargoId]
     * @return: void
     */
    @Override
    public Result<Long> cancelCargo(Long cargoId, Long shipperId) throws Exception {
        return systemCargoService.cancelOnShelfCargo(cargoId, OpsPersonTypeEnum.SHIPPER.getCode(), shipperId);
    }

    /**
     * 查询上架货源
     *
     * @param shipperId 货主Id
     * @Param: [shipperId]
     * @return: List<CargoDTO>
     */
    @Override
    public Result<List<ShipperCargoBriefResponse>> getOnshelfCargos(Long shipperId) {

        if (shipperId == null) {
            return Result.fail(null, ResultCodeEnum.PARAM_ERROR);
        }

        //1.根据货主id查询所有已上架货源
        List<CargoEntity> cargoList = cargoMapper.queryCargoByShipperIdAndState(shipperId, CargoStatusEnum.ON_SHLFE.getCode());

        //2.实体类转化为DTO
        List<ShipperCargoBriefResponse> cargoDTOList = new LinkedList<>();

        //3.遍历转换
        for (CargoEntity cargo : cargoList) {
//            CargoDTO temp = new CargoDTO();
            ShipperCargoBriefResponse temp = new ShipperCargoBriefResponse();
            BeanUtils.copyProperties(cargo, temp);
            cargoDTOList.add(temp);
        }

        log.info("查询到{}已上架{}条货源", shipperId, cargoDTOList.size());

        return Result.success(cargoDTOList);
    }

    /**
     * 查询下架货源
     *
     * @param shipperId 货主Id
     * @Param: [shipperId]
     * @return: List<CargoDTO>
     */
    @Override
    public Result<List<ShipperCargoBriefResponse>> getOffshelfCargos(Long shipperId) {

        //0.参数校验
        if (shipperId == null) {
            return Result.fail(null, ResultCodeEnum.PARAM_ERROR.getCode(), ResultCodeEnum.PARAM_ERROR.getMessage());
        }

        //1.根据货主id查询所有已下架货源
        List<CargoEntity> cargoList = cargoMapper.queryCargoByShipperIdAndState(shipperId, CargoStatusEnum.OFF_SHLFE.getCode());

        //2.实体类转化为DTO
        List<ShipperCargoBriefResponse> cargoDTOList = new LinkedList<>();

        //3.遍历转换
        for (CargoEntity cargo : cargoList) {
            ShipperCargoBriefResponse temp = new ShipperCargoBriefResponse();
            BeanUtils.copyProperties(cargo, temp);
            cargoDTOList.add(temp);
        }

        log.info("查询到{}已下架{}条货源", shipperId, cargoDTOList.size());

        return Result.success(cargoDTOList);
    }

    /**
     * 获取指定货源详情
     *
     * @param cargoId 货源Id
     * @Param: [cargoId]
     * @return: Result<CargoDTO>
     */
    @Override
    public Result<ShipperCargoDetailResponse> getCargoInfoByCargoId(Long cargoId) {
        log.info("开始查询指定货源详情服务：{}", cargoId);

        if (cargoId == null) {
            return Result.fail(null, ResultCodeEnum.PARAM_ERROR.getCode(), ResultCodeEnum.PARAM_ERROR.getMessage());
        }

        //1.查询货源信息
        CargoEntity cargo = cargoMapper.queryCargoByCargoId(cargoId);
        if (cargo == null) {
            return Result.fail(null, ResultCodeEnum.FAIL.getCode(), "无此货源");
        }

        //2.实体类转化为CargoDetailResponse
        ShipperCargoDetailResponse shipperCargoDetailResponse = new ShipperCargoDetailResponse();
        BeanUtils.copyProperties(cargo, shipperCargoDetailResponse);

        return Result.success(shipperCargoDetailResponse);
    }

    /**
     * 上传货源图片
     *
     * @param shipperId 货主Id
     * @param image     图片
     * @return 路径
     */
    @Override
    public Result<String> uploadCargoPhoto(Long shipperId, MultipartFile image) {
        if (shipperId == null || image == null) {
            return Result.fail(null, ResultCodeEnum.PARAM_ERROR.getCode(), "入参错误");
        }
        //判断图片是否合法
        String fileName = image.getOriginalFilename();
        if (Objects.isNull(fileName)) {
            return Result.fail(null, ResultCodeEnum.PARAM_ERROR.getCode(), "参数错误");
        }
        int index = fileName.lastIndexOf(".");
        String suffix = fileName.substring(index);
        if (!".png".equals(suffix) && !".jpg".equals(suffix) && !".jpeg".equals(suffix)) {
            return Result.fail(null, ResultCodeEnum.PARAM_ERROR.getCode(), "请上传png/jpg/jpeg格式的图片文件！");
        }
        //确定文件存放路径
        String relativePath = "/img/cargo/shipper/" + shipperId + "/" + System.currentTimeMillis() + suffix;
        //存储文件
        try {
            Result<Boolean> uploadResult = UploadFileUtils.upload(image, relativePath);
            if (Objects.isNull(uploadResult)) {
                return Result.fail(null, ResultCodeEnum.FAIL.getCode(), "系统繁忙");
            }
            if (!uploadResult.isSuccess()) {
                return Result.fail(null, uploadResult.getCode(), uploadResult.getMessage());
            }
            return Result.success(relativePath);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("文件存储失败" + e.getMessage());
            return Result.fail(null, com.ymm.lulutong.constant.ResultCodeEnum.FAIL.getCode(), "文件存储失败，服务器异常");
        }
    }
}
